package com.ruoyi.wechat.util;

import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.DicConstants;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.tencentCos.CosAppendObject;
import com.ruoyi.common.utils.tencentCos.CosConstants;
import com.ruoyi.system.service.ISysConfigService;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.apache.ibatis.builder.xml.XMLConfigBuilder;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.core.env.Environment;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.xml.sax.InputSource;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.security.KeyStore;
import java.util.*;
import java.util.Map.Entry;

/**
 *
 * @Description: TODO(工具类)
 * @author cuihang
 * @date 2014-12-30 下午2:11:23
 */
@Component
public class CommonUtil {
	@Autowired
	private ISysConfigService configService;

	private static Environment env;
	private static Logger log = LoggerFactory.getLogger(CommonUtil.class);
	// 凭证获取（GET）
	//public final static String token_url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=getid&corpsecret=getsecrect";
private  final static String charset = "UTF-8";
	/**
	 * 发送https请求
	 *
	 * @param requestUrl
	 *            请求地址
	 *            提交的数据
	 * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
	 */
	public static JSONObject doGetURL(String requestUrl) {
		JSONObject jsonObject = null;
		try {
			// 创建SSLContext对象，并使用我们指定的信任管理器初始化
			TrustManager[] tm = { new MyX509TrustManager() };
			SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
			sslContext.init(null, tm, new java.security.SecureRandom());
			// 从上述SSLContext对象中得到SSLSocketFactory对象
			SSLSocketFactory ssf = sslContext.getSocketFactory();

			URL url = new URL(requestUrl);
			HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
			conn.setSSLSocketFactory(ssf);

			conn.setDoOutput(true);
			conn.setDoInput(true);
			conn.setUseCaches(false);
			// 设置请求方式（GET/POST）
			conn.setRequestMethod("GET");


			// 从输入流读取返回内容
			InputStream inputStream = conn.getInputStream();
			InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
			BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
			String str = null;
			StringBuffer buffer = new StringBuffer();
			while ((str = bufferedReader.readLine()) != null) {
				buffer.append(str);
			}

			// 释放资源
			bufferedReader.close();
			inputStreamReader.close();
			inputStream.close();
			inputStream = null;
			conn.disconnect();
			jsonObject = JSONObject.parseObject(buffer.toString());
		} catch (ConnectException ce) {
			log.error("连接超时：{}", ce);
		} catch (Exception e) {
			log.error("https请求异常：{}", e);
		}
		return jsonObject;
	}
	public  JSONObject doPostFile(String requestUrl, String outputStr,String fileNamePart,String requrl) {
		JSONObject jsonObject = new JSONObject();
		try {
			// 创建SSLContext对象，并使用我们指定的信任管理器初始化
			TrustManager[] tm = { new MyX509TrustManager() };
			SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
			sslContext.init(null, tm, new java.security.SecureRandom());
			// 从上述SSLContext对象中得到SSLSocketFactory对象
			SSLSocketFactory ssf = sslContext.getSocketFactory();

			URL url = new URL(requestUrl);
			HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
			conn.setSSLSocketFactory(ssf);

			conn.setDoOutput(true);
			conn.setDoInput(true);
			conn.setUseCaches(false);
			// 设置请求方式（GET/POST）
			conn.setRequestMethod("POST");
			conn.setRequestProperty("Content-Type","application/json; charset=UTF-8");
			// 当outputStr不为null时向输出流写数据
			if (null != outputStr) {
				OutputStream outputStream = conn.getOutputStream();
				// 注意编码格式
				outputStream.write(outputStr.getBytes("UTF-8"));
				outputStream.close();
			}

			// 从输入流读取返回内容
			InputStream inputStream = conn.getInputStream();
			InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
			BufferedInputStream bis = new BufferedInputStream(inputStream);
			//BufferedInputStream  bufferedReader = new BufferedReader(inputStreamReader);
//			String str = null;
//			StringBuffer buffer = new StringBuffer();
//			while ((str = bufferedReader.readLine()) != null) {
//				buffer.append(str);
//			}

			String fileName = fileNamePart+".jpg"; //文件名
			fileName=fileName.replaceAll("/","");
			fileName=fileName.replaceAll("\\\\","");
			fileName=fileName.replaceAll(":","");
			fileName=fileName.replaceAll("\\*","");
			fileName=fileName.replaceAll("\\?","");
			fileName=fileName.replaceAll("\"","");
			fileName=fileName.replaceAll("<","");
			fileName=fileName.replaceAll(">","");
			fileName=fileName.replaceAll("|","");
			// 上传文件路径
			String uploadDir = RuoYiConfig.getUploadPath();
			String filePath="/commissioncode/"+ DateUtils.getDate();
//			String filePath="/headImg";
			String fileAbsolutePath = uploadDir + filePath +"/"+ fileName;
			String imgUrl = requrl + Constants.RESOURCE_PREFIX + "/upload"+filePath +"/"+ fileName;

			File file=new File( uploadDir + filePath);
			if(!file.exists()){
				file.mkdirs();
			}
			OutputStream os = new FileOutputStream(new File(fileAbsolutePath));
			int len;
			byte[] arr = new byte[1024];
			while ((len = bis.read(arr)) != -1) {
				os.write(arr, 0, len);
				os.flush();
			}
			os.close();

			// 释放资源
			bis.close();
			inputStreamReader.close();
			inputStream.close();
			conn.disconnect();
			//jsonObject = JSONObject.parseObject(buffer.toString());
			if(DicConstants.SYS_Y.getCode().equals(configService.selectConfigByKey("cententOSS"))){
				//开启腾讯oss
				Map<String, String> map = new HashMap<>(4);
				map.put("secretKey",configService.selectConfigByKey("secretKey"));
				map.put("secretId",configService.selectConfigByKey("secretId"));
				map.put("area",configService.selectConfigByKey("area"));
				map.put("bucketName",configService.selectConfigByKey("bucketName"));
				imgUrl= CosAppendObject.AppendObjectFromLocal(map,fileName,fileAbsolutePath,"upload"+filePath);
			}
//			if(CosConstants.aliOssOpen){
//				//开启腾讯oss
////                String localFile,String webPath
//				imgUrl= aliOssUtil.uploadLocal(fileAbsolutePath,"upload"+filePath+"/"+fileName);
//				//url= CosAppendObject.AppendObjectFromLocal(fileName,fileAbsolutePath,"upload/"+filePath);
//			}
			jsonObject.put("imgUrl",imgUrl);
			jsonObject.put("fileAbsolutePath",fileAbsolutePath);
		} catch (ConnectException ce) {
			log.error("连接超时：{}", ce);
		} catch (Exception e) {
			log.error("https请求异常：{}", e);
		}
		return jsonObject;
	}
	public static JSONObject doPostStr(String requestUrl, String outputStr) {
		JSONObject jsonObject = null;
		try {
			// 创建SSLContext对象，并使用我们指定的信任管理器初始化
			TrustManager[] tm = { new MyX509TrustManager() };
			SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
			sslContext.init(null, tm, new java.security.SecureRandom());
			// 从上述SSLContext对象中得到SSLSocketFactory对象
			SSLSocketFactory ssf = sslContext.getSocketFactory();

			URL url = new URL(requestUrl);
			HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
			conn.setSSLSocketFactory(ssf);

			conn.setDoOutput(true);
			conn.setDoInput(true);
			conn.setUseCaches(false);
			// 设置请求方式（GET/POST）
			conn.setRequestMethod("POST");

			// 当outputStr不为null时向输出流写数据
			if (null != outputStr) {
				OutputStream outputStream = conn.getOutputStream();
				// 注意编码格式
				outputStream.write(outputStr.getBytes("UTF-8"));
				outputStream.close();
			}

			// 从输入流读取返回内容
			InputStream inputStream = conn.getInputStream();
			InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
			BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
			String str = null;
			StringBuffer buffer = new StringBuffer();
			while ((str = bufferedReader.readLine()) != null) {
				buffer.append(str);
			}

			// 释放资源
			bufferedReader.close();
			inputStreamReader.close();
			inputStream.close();
			inputStream = null;
			conn.disconnect();
			jsonObject = JSONObject.parseObject(buffer.toString());
		} catch (ConnectException ce) {
			log.error("连接超时：{}", ce);
		} catch (Exception e) {
			log.error("https请求异常：{}", e);
		}
		return jsonObject;
	}
	public static JSONObject doPostMap(String requestUrl, Map<String,String> params) throws Exception{
		JSONObject jsonObject = null;
		HttpURLConnection conn = null;
		OutputStream outputStream =null;
		InputStream inputStream=null;
		try {
			// 创建SSLContext对象，并使用我们指定的信任管理器初始化
			TrustManager[] tm = { new MyX509TrustManager() };
			SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
			sslContext.init(null, tm, new java.security.SecureRandom());
			// 从上述SSLContext对象中得到SSLSocketFactory对象
			SSLSocketFactory ssf = sslContext.getSocketFactory();

			URL url = new URL(requestUrl);
			 conn = (HttpsURLConnection) url.openConnection();
			((HttpsURLConnection) conn).setSSLSocketFactory(ssf);

			conn.setDoOutput(true);
			conn.setDoInput(true);
			conn.setUseCaches(false);
			// 设置请求方式（GET/POST）
			conn.setRequestMethod("POST");

			// 当outputStr不为null时向输出流写数据
			if (null != params) {
				 outputStream = conn.getOutputStream();
				// 注意编码格式
				if (params != null) {
					String query = buildQuery(params, charset);
					outputStream.write(query.getBytes(charset));
				}
				outputStream.close();
			}

			// 从输入流读取返回内容
			 inputStream = conn.getInputStream();
			InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
			BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
			String str = null;
			StringBuffer buffer = new StringBuffer();
			while ((str = bufferedReader.readLine()) != null) {
				buffer.append(str);
			}

			// 释放资源
			bufferedReader.close();
			inputStreamReader.close();
			inputStream.close();
			inputStream = null;
			conn.disconnect();
			jsonObject = JSONObject.parseObject(buffer.toString());
		} catch (ConnectException ce) {
			log.error("连接超时：{}", ce);
		} catch (Exception e) {
			log.error("https请求异常：{}", e);
		} finally {
			if (inputStream != null) {
				inputStream.close();
			}
			if (outputStream != null) {
				outputStream.close();
			}
			if (conn != null) {
				conn.disconnect();
			}
		}
		return jsonObject;
	}

	/**
	 * 发送https请求
	 *
	 * @param requestUrl
	 *            请求地址
	 *            请求方式（GET、POST）
	 * @param outputStr
	 *            提交的数据
	 * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
	 */
	public static Map doPostStrMap(String requestUrl, String outputStr) {
		Map result = new HashMap();
		try {
			// 创建SSLContext对象，并使用我们指定的信任管理器初始化
			TrustManager[] tm = { new MyX509TrustManager() };
			SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
			sslContext.init(null, tm, new java.security.SecureRandom());
			// 从上述SSLContext对象中得到SSLSocketFactory对象
			SSLSocketFactory ssf = sslContext.getSocketFactory();

			URL url = new URL(requestUrl);
			HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
			conn.setSSLSocketFactory(ssf);

			conn.setDoOutput(true);
			conn.setDoInput(true);
			conn.setUseCaches(false);
			// 设置请求方式（GET/POST）
			conn.setRequestMethod("POST");

			// 当outputStr不为null时向输出流写数据
			if (null != outputStr) {
				OutputStream outputStream = conn.getOutputStream();
				// 注意编码格式
				outputStream.write(outputStr.getBytes("UTF-8"));
				outputStream.close();
			}

			// 从输入流读取返回内容
			InputStream inputStream = conn.getInputStream();
			InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
			BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
			String str = null;
			StringBuffer buffer = new StringBuffer();
			while ((str = bufferedReader.readLine()) != null) {
				buffer.append(str);
			}

			// 释放资源
			bufferedReader.close();
			inputStreamReader.close();
			inputStream.close();
			inputStream = null;
			conn.disconnect();
			return xmlStrToMap(buffer.toString());
		} catch (ConnectException ce) {
			log.error("连接超时：{}", ce);
		} catch (Exception e) {
			log.error("https请求异常：{}", e);
		}
		return result;
	}
	private static Map xmlStrToMap(String str) {
		Map result = new HashMap();
		StringReader sr = new StringReader(str);
		InputSource is = new InputSource(sr);
		SAXReader reader = new SAXReader();
		try {
			Document document = reader.read(is);
			Element root = document.getRootElement();

			List<Element> elementList = root.elements();

			for (Element e : elementList) {
				result.put(e.getName(), e.getText());
			}

		} catch (DocumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return result;
	}
	public static Map doPostStrMap(String agentNum,String requestUrl, String outputStr,String PKCFilePath) throws Exception{
		KeyStore keyStore = KeyStore.getInstance("PKCS12");
		// 读取本机存放的PKCS12证书文件
		InputStream instream = new FileInputStream(new File(PKCFilePath));//CommonUtil.class.getResourceAsStream(PKCFilePath);//
		try {
			// 指定PKCS12的密码(商户ID)
			keyStore.load(instream, agentNum.toCharArray());
		} finally {
			instream.close();
		}
		SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, agentNum.toCharArray()).build();
		// 指定TLS版本
		SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null, SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
		// 设置httpclient的SSLSocketFactory
		CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
		 HttpPost httppost = new HttpPost(requestUrl);
           HttpEntity reqEntity =new StringEntity(outputStr, "UTF-8");//  .getBytes("UTF-8")
           httppost.setEntity(reqEntity);
	           // System.out.println("executing request " + httppost.getURI());
	            CloseableHttpResponse response = httpclient.execute(httppost);
	            HttpEntity entity = response.getEntity();
	        	InputStream inputStream = entity.getContent();
				InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
				BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
				String str = null;
				StringBuffer buffer = new StringBuffer();
				while ((str = bufferedReader.readLine()) != null) {
					buffer.append(str);
				}

				// 释放资源
				bufferedReader.close();
				inputStreamReader.close();
				inputStream.close();
				inputStream = null;
				 response.close();
				return xmlStrToMap(buffer.toString());
	}

	/*private static Map xmlStrToMap(String str) {
		Map result = new HashMap();
		StringReader sr = new StringReader(str);
		InputSource is = new InputSource(sr);
		SAXReader reader = new SAXReader();
		try {
			Document document = reader.read(is);
			Element root = document.getRootElement();

			List<Element> elementList = root.elements();

			for (Element e : elementList) {
				result.put(e.getName(), e.getText());
			}

		} catch (DocumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return result;
	}*/

	/**
	 * Map<String,String[]> 转 Map<String,String>
	 *
	 * @author cuihang
	 * @date 2015-1-5 下午3:32:04
	 * @param param
	 * @return
	 */
	public static Map<String, String> translateMap(Map<String, String[]> param) {
		Map<String, String> result = new HashMap<String, String>();
		if (param == null)
			return result;
		Iterator it = param.keySet().iterator();
		String key = null;
		while (it.hasNext()) {
			key = String.valueOf(it.next());
			String[] values = param.get(key);
			if (values != null && values.length > 0) {
				result.put(key, values[0]);
			}
		}

		return result;
	}
	private static String buildQuery(Map<String, String> params, String charset) throws IOException {
		if (params == null || params.isEmpty()) {
			return null;
		}

		StringBuilder query = new StringBuilder();
		Set<Entry<String, String>> entries = params.entrySet();
		boolean hasParam = false;

		for (Entry<String, String> entry : entries) {
			String name = entry.getKey();
			String value = entry.getValue();
			// 忽略参数名或参数值为空的参数
			if (areNotEmpty(name, value)) {
				if (hasParam) {
					query.append("&");
				} else {
					hasParam = true;
				}

				query.append(name).append("=").append(URLEncoder.encode(value, charset));
			}
		}

		return query.toString();
	}
	private static boolean areNotEmpty(String... values) {
		boolean result = true;
		if (values == null || values.length == 0) {
			result = false;
		} else {
			for (String value : values) {
				result &= !isEmpty(value);
			}
		}
		return result;
	}

	private static boolean isEmpty(String value) {
		int strLen;
		if (value == null || (strLen = value.length()) == 0) {
			return true;
		}
		for (int i = 0; i < strLen; i++) {
			if ((Character.isWhitespace(value.charAt(i)) == false)) {
				return false;
			}
		}
		return true;
	}
	/**
	*@Description: TODO(根据req返回外网访问的端口)
	* @author cuihang
	*@date 2015-11-27 上午10:39:47
	*@param request
	*@return
	 */
	public static String  getPortByReq( HttpServletRequest request){
		String result="";
		int locport=request.getLocalPort();
		if(locport==9090){
			result=":443";
		}
		return result;
	}
	/**
	*@Description: TODO(根据URL保存图片)
	* @author cuihang
	*@date 2016-3-6 下午3:28:39
	*@param headurl
	*@return
	 */

	public static String downloadIcon(String headurl,String realPath,String savepath,String imgname) {
		URL url;
		String fnName="";
		try {
			url = new URL(headurl);
			HttpURLConnection conn=(HttpURLConnection)url.openConnection();
			conn.connect();
			BufferedInputStream ins=new BufferedInputStream(conn.getInputStream());
			fnName = imgname+".jpg";
			File path = new File(realPath+ savepath + File.separator + fnName);
			File basePath = new File(path.getParent());
			if (!basePath.exists()) {
				basePath.mkdirs();
			}
			FileOutputStream out = new FileOutputStream(path);
			int i;
			while((i=ins.read())!=-1){
				out.write(i);
				}
			out.flush();
			out.close();
			ins.close();
			conn.disconnect();
			String picuri = File.separator + savepath + File.separator + fnName;
			return picuri;
		} catch (IOException e) {
			e.printStackTrace();
			return "";
		}

	}
	public static SqlSession sqlExecutor(ExecutorType executorType) throws IOException{
		String resource = "mybatis/mybatis-config.xml";
		Reader reader =
				Resources.getResourceAsReader(resource);
		InputStream st = Resources.getResourceAsStream(resource);
		String property = env.getProperty("mybatis.configLocation");

		SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
		SqlSessionFactory build = sqlSessionFactoryBuilder.build(st);
		return build.openSession(executorType);
	}

}
